import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Laurens
 */
public class inLine_Temp_Refactor implements RefactoringMethod
{
    /*
     * Initialization and declaration of variables
     */
    String variable = "";
    characterList characters = new characterList();    
    characterEditor characterEditor = new characterEditor();    
    FileEditor fileE = new FileEditor();
    String type = "";
    /*
     * End of initialization and declaration of variables
     */
    
    /**
     * Constructor does nothing
     */
    public inLine_Temp_Refactor()
    {
        //DOES NOTHING
    }

    /**
     * This does the actual inLine temp of a method refactoring
     * @param parameters
     * @return 
     */
    @Override
    public Vector<String> refactor(Vector<String> parameters)
    {
        /*
         * Creates same look and feel for GUI
         */
        try 
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
        catch (Exception ex) 
        {
            Logger.getLogger(Rename_Parameter_Refactor.class.getName()).log(Level.SEVERE, null, ex);
        } 
        Vector<String> result = new Vector<String>();
        String path = "";
        boolean keywords = false;
        boolean punctuation = false;
        String file = "";
        String s = "";
        /*
         * Parameters declaration
         */
        if(parameters.size() > 0)
        {
            if(parameters.get(1) == null)
            {
                variable = JOptionPane.showInputDialog("What variable would you like to change into an inLine Temp?\n");
            }
            else
            {
                variable = parameters.get(1);
            }
            path = parameters.get(0);
            result.add(path);
            keywords = characters.checkKeywords(variable);
            keywords = characters.punctuationCheck(variable);
            if(punctuation)
            {
                result.add("Error you may not use that word, it is a punctuation");
                return result;
            }
            else if(keywords)
            {
                result.add("Error you may not use that word, it is a special keyword in java");
                return result;
            }
            else
            {
                try
                {
                    /*
                     * Reads the file needed to do the inLine_Temp refactor
                     */
                    file = fileE.read(path);
                }
                catch(Exception e)
                {

                }
                Vector<Integer> preCondition = new Vector<Integer>();
                preCondition = preCondition(file, variable);
                if(preCondition.size() == 1)
                {
                    result.add(doInLineConversion(file, variable));
                }
                else
                {
                    result.add("Error you may not inLine temp refactor a value that is initialised twice!");
                    return result;
                }
            }
        }
        else
        {
            result.add("Error, not enough parameters!");
            return result;
        }
        return result;
    }

    /**
     * Converts the class into a class that has inLine temp functionality
     * @param file
     * @param variable
     * @return 
     */
    private String doInLineConversion(String file, String variable) 
    {
        Scanner scanner = new Scanner(file);
        Vector<String> result = new Vector<String>();
        int i = 1;
        int j = lineNumber(file, variable);
        String newFunction = "";
        int openBrackets = 1;
        int closedBrackets = 0;
        Vector<Integer> lineNumbers = lineNumbers(file, variable);
        if(j == 0)
        {
            return "Error that variable is not found";
        }
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == j)
            {
                newFunction = getFunctionName(currentLine);
                for(int k = 0; k < 12; k++)
                {
                    if(currentLine.contains(type+" "+variable+" ="))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+" = "))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+"= "))
                    {   
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(type+" "+variable+"="))
                    {
                        currentLine = scanner.nextLine();
                        i++;
                    }
                    else if(currentLine.contains(" "+characters.keywords().get(k)+" "))
                    {
                        result.add(currentLine);
                        currentLine = scanner.nextLine();
                        k = 0;
                        i++;
                    }
                    else if(currentLine.contains("}"))
                    {
                        closedBrackets++;
                    }
                    else if(currentLine.contains("{"))
                    {
                        openBrackets++;
                    }
                    else if(openBrackets == closedBrackets)
                    {
                        k = 12;
                    }
                }
                for(int u = 0; u < lineNumbers.size(); u++)
                {
                    result.add(getFunctionCalls(lineNumbers.get(u), file, variable, "get"+variable.toUpperCase()+"()"));
                }
            }
                    
            else if(i == determineLength(file)-2)
            {
                result.add(currentLine);
                result.add("\n");
                result.add("public " + type + " " +"get"+variable.toUpperCase()+"()");
                result.add("{");
                result.add("\treturn " + newFunction);
                result.add("}");
                result.add("\n");
            }
            else
            {
                boolean line = false;
                for(int p = 0; p < characters.characterListMethod().size(); p++)
                {
                    if(currentLine.contains(characters.characterListMethod().get(p)+variable))
                    {
                        line = true;
                        p = characters.characterListMethod().size();
                    }
                    else if(currentLine.contains(variable+characters.characterListMethod().get(p)))
                    {
                        line = true;
                        p = characters.characterListMethod().size();
                    }
                }
                if(!line)
                {
                    result.add(currentLine);
                }
            }
            i++;
        }
        String output = "";
        for(int y = 0; y < result.size(); y++)
        {
            output += result.get(y) + "\n";
        }
        return output;
    }
    
    /**
     * Gets the linenumber of the initialization of the variable
     * @param file
     * @param variable
     * @return 
     */
    public int lineNumber(String file, String variable)
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        int _lineNumber = 0;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            for(int k = 0; k < 12; k++)
            {
                if(currentLine.contains(characters.keywords().get(k)+" "+variable+" ="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+"="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(characters.keywords().get(k)+" "+variable+"="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+" ="))
                {
                    type = characters.keywords().get(k);
                    _lineNumber = i;
                    return _lineNumber;
                }    
            }
            i++;
        }
        return _lineNumber;
    }

    /**
     * Returns the functionality after the equals
     * @param currentLine
     * @return 
     */
    private String getFunctionName(String currentLine) 
    {
        StringTokenizer st = new StringTokenizer(currentLine);
        String output = "";
        while(st.hasMoreTokens())
        {
            String current = st.nextToken();
            if(current.equals("="))
            {
                for(int i = 0; st.hasMoreTokens(); i++)
                {
                    output += st.nextToken();
                    return output;
                }
            }
        }
        return output;
    }

    /**
     * Returns a vector with all the lineNumbers that use variable
     * @param file
     * @param variable
     * @return 
     */
    public Vector<Integer> lineNumbers(String file, String variable)
    {
        Scanner scanner = new Scanner(file);
        Vector<Integer> result = new Vector<Integer>();
        int i = 1;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(currentLine.contains(variable))
            {
                result.add(i);
            }
            i++;
        }
        Vector<Integer> lines = new Vector<Integer>();
        for(int y = 0; y < result.size(); y++)
        {
            if(y == 0)
            {
                
            }
            else
            {
                lines.add(result.get(y));
            }
        }
        return lines;
    }
    
    /**
     * Returns a vector with the string where the calls to the function have been changed
     * @param lineNumbers
     * @param file
     * @param variable
     * @param newFunction
     * @return 
     */
    private String getFunctionCalls(int lineNumbers, String file, String variable, String newFunction) 
    {
        Scanner scanner = new Scanner(file);
        Vector<String> result = new Vector<String>();
        int z = 0;
        int i = 1;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(i == lineNumbers)
            {
                result.add(currentLine.replaceAll(variable, newFunction));
                z++;
            }
            i++;
        }
        String output = "";
        for(int q = 0; q < result.size(); q++)
        {
            output += result.get(q);
        }
        return output;
    }

    /**
     * Returns the length of the function you want to delete
     * @param lineNumbers
     * @param file
     * @return 
     */
    private int determineLength(String file) 
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        int length = 1;
        int closedBrackets = 0;
        int openBrackets = 0;        
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(currentLine.contains("{"))
            {
                openBrackets++;
            }
            else if(currentLine.contains("}"))
            {
                closedBrackets++;
            }
            i++;
            if(openBrackets != 0)
            {
                if(openBrackets == closedBrackets)
                {
                    length = i;
                    return length;
                }
            }
        }
        return length;
    }
    
    /**
     * Gets the linenumber of the initialization of the variable
     * @param file
     * @param variable
     * @return 
     */
    public Vector<Integer> preCondition(String file, String variable)
    {
        Scanner scanner = new Scanner(file);
        int i = 1;
        Vector<Integer> lineNumber = new Vector<Integer>();
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            for(int k = 0; k < 12; k++)
            {
                if(currentLine.contains(characters.keywords().get(k)+" "+variable+" ="))
                {
                    lineNumber.add(i);
                    
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+"="))
                {
                    lineNumber.add(i);
                }    
                else if(currentLine.contains(characters.keywords().get(k)+" "+variable+"="))
                {
                    lineNumber.add(i);
                }    
                else if(currentLine.contains(" "+characters.keywords().get(k)+" "+variable+" ="))
                {
                    lineNumber.add(i);
                }    
            }
            i++;
        }
        return lineNumber;
    }

    /**
     * Returns a description of the current refactoring method
     * @return 
     */
    @Override
    public String description() 
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    public static void main(String[] args)
    {
        inLine_Temp_Refactor i = new inLine_Temp_Refactor();
        System.out.println("asd");
        Vector<String> k = i.possibleInLineRefactoring("public\n\nint k = 0");
        System.out.println(k);
        System.out.println("asds");
    }
    
    public Vector<String> possibleInLineRefactoring(String file)
    {
        Vector<String> result = new Vector<String>();
        Scanner scanner = new Scanner(file);
        int count = 0;
        while(scanner.hasNext())
        {
            String currentLine = scanner.nextLine();
            if(currentLine.contains("="))
            {
                StringTokenizer st = new StringTokenizer(currentLine, "=");
                String current = st.nextToken();
                System.out.println(st.nextToken());
                if(current.contains("int"))
                {
                        count++;
                }
            }
            else
            {
                
            }
        }
        if(count == 1)
        {
            
        }
        return result;
    }
}
